use docopt::Docopt;
use core::{Shell, MultiShell, ShellConfig};
-use term::color::{BLACK};
+use term::color::{BLACK, RED};
pub use util::{CargoError, CliError, CliResult, human};
MultiShell::new(out, err, verbose)
}
+
+// `output` print variant error strings to either stderr or stdout.
+// For fatal errors, print to stderr;
+// and for others, e.g. docopt version info, print to stdout.
+fn output(caption: Option<String>, detail: Option<String>,
+ shell: &mut MultiShell, fatal: bool) {
+ let std_shell = if fatal {shell.err()} else {shell.out()};
+ if let Some(caption) = caption {
+ let color = if fatal {RED} else {BLACK};
+ let _ = std_shell.say(caption, color);
+ }
+ if let Some(detail) = detail {
+ let _ = std_shell.say(detail, BLACK); // always black
+ }
+}
+
pub fn handle_error(err: CliError, shell: &mut MultiShell) {
log!(4, "handle_error; err={}", err);
let CliError { error, exit_code, unknown } = err;
+ let verbose = shell.get_verbose();
+ let fatal = exit_code == 1; // exit_code == 0 is non-fatal error
if unknown {
- let _ = shell.error("An unknown error occurred");
+ output(Some("An unknown error occurred".to_string()), None, shell, fatal);
} else if error.to_string().len() > 0 {
- let _ = shell.error(error.to_string());
+ output(Some(error.to_string()), None, shell, fatal);
}
if error.cause().is_some() || unknown {
- let _ = shell.concise(|shell| {
- shell.err().say("\nTo learn more, run the command again with --verbose.", BLACK)
- });
+ if !verbose {
+ output(None,
+ Some("\nTo learn more, run the command again with --verbose.".to_string()),
+ shell, fatal);
+ }
}
- let _ = shell.verbose(|shell| {
+ if verbose {
if unknown {
- let _ = shell.error(error.to_string());
+ output(Some(error.to_string()), None, shell, fatal);
}
if let Some(detail) = error.detail() {
- let _ = shell.err().say(format!("{}", detail), BLACK);
+ output(None, Some(detail), shell, fatal);
}
if let Some(err) = error.cause() {
let _ = handle_cause(err, shell);
}
- Ok(())
- });
+ }
std::os::set_exit_status(exit_code as int);
}